package unimelb.filesync.server.protocol;

import unimelb.filesync.common.message.NetworkMessage;
import unimelb.filesync.common.message.RequestBlockSizeRole;
import unimelb.filesync.common.message.ResponseBlockSizeRole;
import unimelb.filesync.common.misc.ProtocolContext;
import unimelb.filesync.common.network.NetworkConnection;
import unimelb.filesync.common.network.NetworkService;
import unimelb.filesync.common.protocol.IFileSyncPhase;

public class AcceptBlockSizeRolePhase implements IFileSyncPhase {

    private final NetworkService networkService;

    private final ProtocolContext context;

    public AcceptBlockSizeRolePhase(ProtocolContext context) {
        super();
        this.networkService = new NetworkService();
        this.context = context;
    }

    @Override
    public void execute() {
        System.out.println("Reading block size role");
        
        final NetworkConnection conn = context.getObject(ProtocolContext.HOT_LINE_CONNECTION);
        final NetworkMessage msg = networkService.readMessage(conn);
        if (msg == null) {
            System.exit(0);
        }
        final RequestBlockSizeRole content = msg.getContent();

        ResponseBlockSizeRole response = null;
        if (content.getBlockSize() < 0) {
            response = new ResponseBlockSizeRole("Block size must be greater than 0");
        } else if (!ProtocolContext.ROLE_SOURCE.equalsIgnoreCase(content.getRole()) && !ProtocolContext.ROLE_DESTINATION.equalsIgnoreCase(content.getRole())) {
            response = new ResponseBlockSizeRole("Invalid role:" + content.getRole());
        } else {
            context.addObject(ProtocolContext.BLOCK_SIZE, content.getBlockSize());

            String serverRole = null;
            if (ProtocolContext.ROLE_SOURCE.equalsIgnoreCase(content.getRole())) {
                serverRole = ProtocolContext.ROLE_DESTINATION;
            } else if (ProtocolContext.ROLE_DESTINATION.equalsIgnoreCase(content.getRole())) {
                serverRole = ProtocolContext.ROLE_SOURCE;
            }
            context.addObject(ProtocolContext.ROLE, serverRole);

            response = new ResponseBlockSizeRole();
        }
        networkService.writeMessage(NetworkMessage.createBlockSizeRoleResponseMsg(response), conn);

        if (!response.isSuccess()) {
            throw new RuntimeException(response.getErrorMessage());
        }
    }
}
